package api

import (
	"context"
	"fmt"
	"strings"
	"time"

	"zhonghui/console/models"
	"zhonghui/console/service"
	"zhonghui/console/structs"
	"zhonghui/console/warehouse/cfgx"
	"zhonghui/console/warehouse/dbx"
	"zhonghui/console/warehouse/dbx/cache_main"
	"zhonghui/console/warehouse/dbx/db_zh_kernel"
	"zhonghui/console/warehouse/dbx/db_zh_kernel_slave"
	"zhonghui/console/warehouse/envx"
	"zhonghui/console/warehouse/helperx"
	"zhonghui/console/warehouse/logx"
	"zhonghui/console/warehouse/modelx/model_zh_kernel"
	"zhonghui/console/warehouse/respx"

	"github.com/gin-gonic/gin"
)

func getContent(s models.Store, corpId, configId string) (*structs.PageContent, *structs.PageContent, error) {
	configs, err := s.GetDefaultMiniConfig(context.Background(), models.GetDefaultMiniConfigParams{
		ConfigID: configId,
		Corpid:   corpId,
	})
	if err != nil {
		return nil, nil, err
	}
	result := GetMpConfigByIDResponse{}
	dr := GetMpConfigByIDResponse{}
	for _, v := range configs {
		if v.ConfigID == "default" {
			dr.ConfigId = v.ConfigID
			dr.Title = v.Title
			dr.Content = v.Content
			dr.Guarantee = v.Guarantee
		} else {
			result.ConfigId = v.ConfigID
			result.Title = v.Title
			result.Content = v.Content
			result.Guarantee = v.Guarantee
		}
	}
	if result.ConfigId == "" {
		result = dr
	}
	pageOne := strings.Split(result.Content, "#")
	pageTwo := strings.Split(result.Guarantee, "#")
	if len(pageOne) == 3 && len(pageTwo) == 3 {
		return &structs.PageContent{
				Head:     pageOne[0],
				Describe: pageOne[1],
				Footer:   pageOne[2],
			}, &structs.PageContent{
				Head:     pageTwo[0],
				Describe: pageTwo[1],
				Footer:   pageTwo[2],
			}, nil
	}
	return &structs.PageContent{Head: result.Content}, &structs.PageContent{Head: result.Guarantee}, nil
}

func (server *Server) GetH5Marketing(c *gin.Context) {
	h := c.Query("record_hash")
	scene := c.Query("scene")
	if scene == "" {
		scene = "success"
	}

	isTest := strings.HasPrefix(h, "TTSS_")

	recordHash := h
	if isTest {
		p := strings.Split(h, "_")
		recordHash = p[1]
	}

	// 解析ID
	id, _ := helperx.HashIdDecode(recordHash)

	record := model_zh_kernel.SysSmsRecord{}
	if err := db_zh_kernel_slave.ClientCtx(c).Where("id = ?", id).Take(&record).Error; err != nil {
		respx.Alert(c, "无法找到该记录")
		return
	}

	task := model_zh_kernel.SysTask{}
	if err := db_zh_kernel_slave.ClientCtx(c).Where("id = ?", record.TaskID).Take(&task).Error; err != nil {
		respx.Alert(c, "无法找到该记录")
		return
	}

	// 测试任务不上报
	if !isTest {
		switch scene {
		case "success":
			if task.SmsTemplate != "6a7559757a1845f1aaaf74fe5d24d1c3" {
				service.ReportData(record.TaskID, record.Phone, structs.ReportKindInsurancePolicy, "")
			}
		case "upgrade":
			service.ReportData(record.TaskID, record.Phone, structs.ReportKindInsurancePolicyUpgrade, "")
		}
	}

	resp := structs.GetH5MarketingResp{
		MpSchemaPolicy: record.MpSchema,
		MpSchemaGift:   record.MpSchema,
	}

	// 取一下测试用的schema
	if isTest {
		resp.MpSchemaPolicy = cache_main.Client().Get(c, dbx.RedisPrefix(fmt.Sprintf("mp_schema_for_test_%s", h))).Val()
		resp.MpSchemaGift = cache_main.Client().Get(c, dbx.RedisPrefix(fmt.Sprintf("mp_schema2_for_test_%s", h))).Val()
	}

	respx.Success(c, resp, nil)
}

func (server *Server) GetMpMarketing(c *gin.Context) {
	h := c.Query("record_hash")
	code := c.Query("code")

	isTest := strings.HasPrefix(h, "TTSS_")
	cfg := cfgx.Cfg().GetStringMapString("wx")

	recordHash := h
	if isTest {
		p := strings.Split(h, "_")
		recordHash = p[1]
	}

	// 解析ID
	id, _ := helperx.HashIdDecode(recordHash)

	record := model_zh_kernel.SysSmsRecord{}
	if err := db_zh_kernel.ClientCtx(c).Where("id = ?", id).Take(&record).Error; err != nil {
		respx.Alert(c, "无法找到该记录")
		return
	}

	configId, qr, err := service.GetCorpQrcodeById(record.ID)
	if err != nil {
		respx.Alert(c, "获取信息失败")
		return
	}

	// 非测试任务，才上报
	if !isTest {
		service.ReportData(record.TaskID, record.Phone, structs.ReportKindViewMp, "")
	}

	// 返回内容
	pageOne, PageTwo, err := getContent(server.store, cfg["corp_id"], configId)
	if err != nil {
		respx.Alert(c, "获取信息失败")
		return
	}

	// 处理小程序
	unionId, openId := service.MpCode2User(c, code)
	logx.ZapTrace(c).Infow("获取微信open_id结果", "open_id", openId, "union_id", unionId)

	if unionId != "" {
		db_zh_kernel.ClientCtx(c).Exec("update sys_sms_record set union_id = ?, open_id = ? where id = ? and union_id = '' and open_id = ''", unionId, openId, record.ID)

		externalUserid := ""
		pendingId := ""

		accessToken, err := server.store.GetAccessTokenByCorpId(context.Background(), cfg["corp_id"])
		if err != nil {
			logx.ZapTrace(c).Errorw("GetMpMarketing GetAccessTokenByCorpId", "corp_id", cfg["corp_id"], "err", err)
		} else {
			resp, err := service.UnionId2ExternalUserId(unionId, openId, accessToken, 0)
			if err != nil {
				logx.ZapTrace(c).Errorw("GetMpMarketing UnionId2ExternalUserId", "unionId", unionId, "openId", openId, "err", err)
			}
			if resp.Errcode != 0 {
				logx.ZapTrace(c).Errorw("GetMpMarketing UnionId2ExternalUserId resp", "unionId", unionId, "openId", openId, "err", resp.Errmsg)
			} else {
				externalUserid = resp.ExternalUserid
				pendingId = resp.PendingId
			}
		}

		db_zh_kernel.ClientCtx(c).
			Exec("update sys_sms_record set pending_id = ?, external_userid = ? where id = ? and pending_id = '' and external_userid = ''",
				pendingId, externalUserid, record.ID)
	}

	resp := structs.GetMpMarketingResp{
		PageOne:  *pageOne,
		PageTwo:  *PageTwo,
		ConfigId: configId,
		Qrcode:   qr,
	}

	respx.Success(c, resp, nil)
}

func (server *Server) GetDwz(c *gin.Context) {
	t, _ := c.GetQuery("t")
	h, _ := c.GetQuery("h")

	t = "p4"

	if t == "" || h == "" {
		logx.ZapTrace(c).Infow("dwz日志-没参数")
		c.String(200, "ok")
		return
	}

	isTest := strings.HasPrefix(h, "TTSS_")
	testPhone := ""

	// 获取保险产品原始地址
	productUrl := service.ParseLocalDwz(t)

	if c.GetHeader("User-Agent") == "Go-http-client/2.0" {
		c.Redirect(302, productUrl)
		return
	}

	recordHash := h
	if isTest {
		p := strings.Split(h, "_")
		recordHash = p[1]
		testPhone = p[2]
	}

	// 解析record
	recordID, _ := helperx.HashIdDecode(recordHash)

	// 查询记录，找不到的话直接跳转原始产品网址
	record := model_zh_kernel.SysSmsRecord{}
	if err := db_zh_kernel_slave.ClientCtx(c).Where("id = ?", recordID).Take(&record).Error; err != nil {
		logx.ZapTrace(c).Infow("dwz日志-找不到记录")
		c.Redirect(302, productUrl)
		return
	}

	// 开始生成小程序schema，找不到的话直接跳转原始产品网址，并带上手机
	schema := ""
	if c.Query("mp") == "1" {
		mpPath := "/pages/otherInsurance/policy"
		if !envx.InProd() {
			mpPath = "/insurance/policy"
		}
		schema = service.GenMpSchema(h, mpPath)
		if schema == "" {
			logx.ZapTrace(c).Errorw("dwz日志-生成小程序schema失败", "record", record)
		}
	}

	if !isTest {
		db_zh_kernel.ClientCtx(c).Model(model_zh_kernel.SysSmsRecord{}).Where("id = ?", record.ID).Updates(map[string]interface{}{
			"mp_schema":  schema,
			"mp_schema2": schema,
			"ua":         c.GetHeader("User-Agent"),
			"ip":         c.ClientIP(),
		})
	} else {
		// 存一下测试用的mpSchema
		cache_main.Client().Set(c, dbx.RedisPrefix(fmt.Sprintf("mp_schema_for_test_%s", h)), schema, time.Hour*24*14)
		cache_main.Client().Set(c, dbx.RedisPrefix(fmt.Sprintf("mp_schema2_for_test_%s", h)), schema, time.Hour*24*14)
	}

	// 判断设备指纹，决定是否返回sensitive_key
	sensitiveKey := service.HandleSensitiveKey(c, record.Phone, h)

	// 拼接最终的跳转网址
	// https://channelh5.pubmi.cn/normalProduct/jhbaoDetail?channel=ZT19121701&phone=186111111234&record_hash=TTSS_111111&sensitive_key=xxx
	to := fmt.Sprintf("%s&phone=%s&record_hash=%s&sensitive_key=%s", productUrl, record.Phone, h, sensitiveKey)
	if isTest {
		to = fmt.Sprintf("%s&phone=%s&record_hash=%s&sensitive_key=", productUrl, testPhone, h)
	}
	if t == "p3" {
		to = fmt.Sprintf("%s&record_hash=%s&policyIds=%s", productUrl, h, service.PhoneToIds(record.Phone))
	}

	// 非测试任务，才上报
	if !isTest {
		service.ReportData(record.TaskID, record.Phone, structs.ReportKindSmsClick, "")
	}

	c.Redirect(302, to)
}
